/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * HotKeyJDialog.java
 *
 * Created on 2010-12-21, 10:50:57
 */
package org.lifxue.jqda.ui;

import java.awt.Dimension;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import javax.swing.DefaultCellEditor;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.DefaultTableModel;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.lifxue.jqda.jintellitype.GlobalHotkeyResourceManagement;
import org.lifxue.jqda.util.GlobalVar;

/**
 *
 * @author lifxue
 */
public class HotKeyJDialog extends javax.swing.JDialog {

    private static Log logger = LogFactory.getLog(HotKeyJDialog.class);
    private HashMap<String, String> HT_HOTKEY;
    private static HotKeyJDialog hotkey;

    public static HotKeyJDialog getInstance(boolean modal) {
        synchronized (HotKeyJDialog.class) {
            if (hotkey == null) {
                hotkey = new HotKeyJDialog(modal);
            }
        }
        return hotkey;
    }

    public HotKeyJDialog(boolean modal) {
        super(new javax.swing.JFrame(), modal);

        init();

        initComponents();

        initTableData();

        //屏幕位置
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        Dimension frameSize = getSize();
        setLocation(new Point((screenSize.width - frameSize.width) / 2,
                (screenSize.height - frameSize.width) / 2));

    }

    /** Creates new form HotKeyJDialog
     * @param parent
     * @param modal
     */
    public HotKeyJDialog(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        hotKeyjTable = new javax.swing.JTable();
        addHotKeyjButton = new javax.swing.JButton();
        delHotKeyjButton = new javax.swing.JButton();
        jSeparator1 = new javax.swing.JSeparator();
        canceljButton = new javax.swing.JButton();
        okjButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("热键设置");

        jScrollPane1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jScrollPane1MouseClicked(evt);
            }
        });

        JTextField j = new JTextField();
        j.addKeyListener(keyAdapter);
        hotKeyjTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "标识", "组合键", "程序名称", "全路径"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.Integer.class, java.lang.String.class, java.lang.String.class, java.lang.String.class
            };
            boolean[] canEdit = new boolean [] {
                false, true, false, false
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        jScrollPane1.setViewportView(hotKeyjTable);
        hotKeyjTable.getColumnModel().getColumn(0).setMinWidth(35);
        hotKeyjTable.getColumnModel().getColumn(0).setPreferredWidth(35);
        hotKeyjTable.getColumnModel().getColumn(0).setMaxWidth(50);
        hotKeyjTable.getColumnModel().getColumn(1).setMinWidth(100);
        hotKeyjTable.getColumnModel().getColumn(1).setPreferredWidth(100);
        hotKeyjTable.getColumnModel().getColumn(1).setMaxWidth(120);
        hotKeyjTable.getColumnModel().getColumn(1).setCellEditor(new TableEditor(j));
        hotKeyjTable.getColumnModel().getColumn(2).setMinWidth(80);
        hotKeyjTable.getColumnModel().getColumn(2).setPreferredWidth(80);
        hotKeyjTable.getColumnModel().getColumn(2).setMaxWidth(150);
        hotKeyjTable.getColumnModel().getColumn(3).setPreferredWidth(100);

        addHotKeyjButton.setText("增加热键");
        addHotKeyjButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addHotKeyjButtonActionPerformed(evt);
            }
        });

        delHotKeyjButton.setText("删除热键");
        delHotKeyjButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                delHotKeyjButtonActionPerformed(evt);
            }
        });

        canceljButton.setText("取消");
        canceljButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                canceljButtonActionPerformed(evt);
            }
        });

        okjButton.setText("保存");
        okjButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                okjButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 541, Short.MAX_VALUE))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(21, 21, 21)
                        .addComponent(addHotKeyjButton)
                        .addGap(18, 18, 18)
                        .addComponent(delHotKeyjButton))
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 541, Short.MAX_VALUE)))
                .addContainerGap())
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(411, Short.MAX_VALUE)
                .addComponent(okjButton)
                .addGap(18, 18, 18)
                .addComponent(canceljButton)
                .addGap(20, 20, 20))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 172, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(addHotKeyjButton)
                    .addComponent(delHotKeyjButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(canceljButton)
                    .addComponent(okjButton))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void canceljButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_canceljButtonActionPerformed
        // TODO add your handling code here:
        //系统热键
        GlobalHotkeyResourceManagement.initResources();
        GlobalHotkeyResourceManagement.addListener();

        closeEditing();
        setVisible(false);
        dispose();
        hotkey = null;

    }//GEN-LAST:event_canceljButtonActionPerformed

    private void okjButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okjButtonActionPerformed
        // TODO add your handling code here:

        //int type = JOptionPane.CLOSED_OPTION;
        //String message = "重启后才能生效！";
        //JOptionPane.showConfirmDialog(this, message, "提示信息", type);

        closeEditing();
        GlobalVar.HOTKEY = HT_HOTKEY;

        canceljButtonActionPerformed(evt);

    }//GEN-LAST:event_okjButtonActionPerformed

    private void addHotKeyjButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addHotKeyjButtonActionPerformed
        // TODO add your handling code here:
        closeEditing();
        //建立文件选择框对象
        JFileChooser fc = new JFileChooser();
        fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
        FileNameExtensionFilter filter = new FileNameExtensionFilter(
                "可执行文件", "exe", "bat", "lnk");
        fc.setFileFilter(filter);

        //设定文件选择框标题
        fc.setDialogTitle("选择可执行文件");
        //显示文件选择框，在选择后将结果储存到returnVal变量中
        int returnVal = fc.showSaveDialog(this);
        //如果用户选择了文件，并点击了"Opne/打开"按钮，显示用户选择的文件全名路径，
        //如果用户点击"Close/关闭"按钮，以及其它方式退出文件选择框，则什么也不做。
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            if (file == null) {
                return;
            }
            if (isExistPath(file)) {
                int type = JOptionPane.CLOSED_OPTION;
                String message = "你选择的文件已经在表格中了！";
                JOptionPane.showConfirmDialog(this, message, "提示信息", type);
                return;
            }
            Integer maxid = findMaxID() + 1;
            addTableRow(file, maxid);
            addOneHotKey(file, maxid);

        }

    }//GEN-LAST:event_addHotKeyjButtonActionPerformed

    private void delHotKeyjButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_delHotKeyjButtonActionPerformed
        // TODO add your handling code here:
        closeEditing();
        javax.swing.table.DefaultTableModel model = (javax.swing.table.DefaultTableModel) hotKeyjTable.getModel();
        int allcount = model.getRowCount();
        int row = hotKeyjTable.getSelectedRow();
        if (row < 0) {
            return;
        }
        String filePath = model.getValueAt(row, 3).toString();
        model.removeRow(row);
        model.setRowCount(allcount - 1);

        HT_HOTKEY.remove(filePath);

    }//GEN-LAST:event_delHotKeyjButtonActionPerformed

    private void jScrollPane1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jScrollPane1MouseClicked
        // TODO add your handling code here:
        closeEditing();
    }//GEN-LAST:event_jScrollPane1MouseClicked

    /**
     * 关闭table的编辑状态
     */
    private void closeEditing() {
        if (hotKeyjTable.isEditing()) {
            hotKeyjTable.getCellEditor().stopCellEditing();
        }
    }

    private void addOneHotKey(File file, Integer id) {
        String filePath = file.getPath();//全路径
        String mod = id.toString();
        HT_HOTKEY.put(filePath, mod);
    }

    /**
     *在表格中增加一行数据 
     * @param file
     */
    private void addTableRow(File file, Integer id) {
        Object[] obj = new Object[4];
        obj[0] = id;
        obj[1] = "";
        obj[2] = file.getName().toLowerCase(Locale.CHINESE);
        obj[3] = file.getPath();
        ((javax.swing.table.DefaultTableModel) hotKeyjTable.getModel()).addRow(obj);

    }

    private boolean isExistPath(File file) {
        boolean exist = false;
        javax.swing.table.DefaultTableModel model = (javax.swing.table.DefaultTableModel) hotKeyjTable.getModel();
        int allcount = model.getRowCount();
        for (int i = allcount - 1; i >= 0; i--) {
            Object temp = model.getValueAt(i, 3);
            if (temp.toString().equals(file.getPath())) {
                exist = true;
                break;
            }
        }
        return exist;
    }

    /**
     * 从表格中找出最大标识
     * @return
     */
    private Integer findMaxID() {
        Integer max = new Integer(0);

        javax.swing.table.DefaultTableModel model = (javax.swing.table.DefaultTableModel) hotKeyjTable.getModel();
        int allcount = model.getRowCount();
        for (int i = allcount - 1; i >= 0; i--) {
            Integer temp = (Integer) model.getValueAt(i, 0);
            if (temp > max) {
                max = temp;
            }
        }
        return max;
    }

    /**
     * 初始化数据
     */
    private void init() {
        HT_HOTKEY = GlobalVar.HOTKEY;
        GlobalHotkeyResourceManagement.removerListener();
        GlobalHotkeyResourceManagement.unregister();
    }

    /**
     * 初始化表格数据
     */
    private void initTableData() {
        DefaultTableModel model = (DefaultTableModel) hotKeyjTable.getModel();
        Iterator i = HT_HOTKEY.entrySet().iterator();
        while (i.hasNext()) {
            Object[] obj = new Object[4];
            String modkey = "";
            String fileName = "";

            java.util.Map.Entry entry = (java.util.Map.Entry) i.next();
            String key = (String) entry.getKey(); //返回与此项对应的键
            String mod = (String) entry.getValue(); //返回与此项对应的值

            String[] paths = key.split("\\\\");
            fileName = paths[paths.length - 1];
            String[] tempmod = mod.split(":");
            for (int l = 1; l < tempmod.length; l++) {
                modkey += tempmod[l] + "+";
            }
            if (modkey.indexOf("+") > -1) {
                modkey = modkey.substring(0, modkey.length() - 1);
            }
            obj[0] = tempmod[0];
            obj[1] = modkey;
            obj[2] = fileName;
            obj[3] = key;
            model.addRow(obj);
        }


    }

    private class TableEditor extends DefaultCellEditor {

        public TableEditor(JTextField j) {
            super(j);
        }

        @Override
        public boolean stopCellEditing() {
            String value = (String) getCellEditorValue();
            String[] tempmod = value.split("\\+");
            StringBuilder sb = new StringBuilder();
            for (int l = 0; l < tempmod.length - 1; l++) {
                sb.append(tempmod[l]);
                sb.append(":");
            }
            sb.append(tempmod[tempmod.length - 1]);

            boolean is = false;
            if("Alt:Space".equals(sb.toString())){//调用主窗口的热键
                return false;
            }
            Iterator j = HT_HOTKEY.entrySet().iterator();
            while (j.hasNext()) {
                java.util.Map.Entry entry = (java.util.Map.Entry) j.next();
                String mod = (String) entry.getValue(); //返回与此项对应的值
                int indexmod = mod.indexOf(":");
                String submod = "";
                if (indexmod > -1) {
                    submod = mod.substring(indexmod+1);
                }
                if(submod.equals(sb.toString())){
                    is = true;
                    break;
                }

            }
            if(is){
                return false;
            }

            try {
                //保存组合键信息到数组中
                DefaultTableModel model = (DefaultTableModel) hotKeyjTable.getModel();
                int selectedid = hotKeyjTable.getSelectedRow();
                String filePath = model.getValueAt(selectedid, 3).toString();
                Iterator i = HT_HOTKEY.entrySet().iterator();
                while (i.hasNext()) {
                    java.util.Map.Entry entry = (java.util.Map.Entry) i.next();
                    String key = (String) entry.getKey(); //返回与此项对应的键
                    String mod = (String) entry.getValue(); //返回与此项对应的值
                    String submod = mod;
                    int indexmod = mod.indexOf(":");
                    if (indexmod > -1) {
                        submod = mod.substring(0, indexmod);
                    }
                    if (key.equals(filePath)) {
                        for (int l = 0; l < tempmod.length; l++) {
                            submod += ":" + tempmod[l];
                        }
                        HT_HOTKEY.put(key, submod);
                        break;
                    }
                }


            } catch (NumberFormatException e) {
                logger.debug(e);
            }
            return super.stopCellEditing();
        }
    }
    private KeyAdapter keyAdapter = new KeyAdapter() {

        @Override
        public void keyPressed(KeyEvent e) {
            //按下ctrl
            if (e.isControlDown()) {
                String modifiers = KeyEvent.getKeyModifiersText(e.getModifiers());
                String text = KeyEvent.getKeyText(e.getKeyCode());
                ((JTextField) e.getComponent()).setText(modifiers + "+" + text);
            } else if (e.isAltDown()) {
                String modifiers = KeyEvent.getKeyModifiersText(e.getModifiers());
                String text = KeyEvent.getKeyText(e.getKeyCode());
                ((JTextField) e.getComponent()).setText(modifiers + "+" + text);
            }
        }
    };

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                HotKeyJDialog dialog = new HotKeyJDialog(new javax.swing.JFrame(), true);
                dialog.addWindowListener(new java.awt.event.WindowAdapter() {

                    @Override
                    public void windowClosing(java.awt.event.WindowEvent e) {
                        System.exit(0);
                    }
                });
                dialog.setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addHotKeyjButton;
    private javax.swing.JButton canceljButton;
    private javax.swing.JButton delHotKeyjButton;
    private javax.swing.JTable hotKeyjTable;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JButton okjButton;
    // End of variables declaration//GEN-END:variables
}
